home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / zoo21src.lha / zoo / zoolist.c < prev    next >
C/C++ Source or Header  |  1992-11-20  |  19KB  |  594 lines

  1. #ifndef LINT
  2. /* derived from: zoolist.c 2.27 88/08/15 11:03:16 */
  3. static char sccsid[]="$Source: g:/newzoo\RCS\zoolist.c,v $\n\
  4. $Id: zoolist.c,v 1.4 1991/07/24 23:58:04 bjsjr Rel $";
  5. #endif /* LINT */
  6.  
  7. /*
  8. If TRACE_LIST is defined, any list command may be followed
  9. by 'D' to show verbose information about each directory
  10. entry in the archive.   Do not define both TRACE_LIST and
  11. TRACE_IO else a symbol conflict will occur and in any case
  12. duplicate information will be dumped.
  13. */
  14.  
  15. /* #define TRACE_LIST */
  16.  
  17. /*
  18. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  19. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  20. */
  21. #include "options.h"
  22. #include "portable.h"
  23. #include "zoomem.h"  /* to get ZOOCOUNT */
  24.  
  25. /* Lists files in archive */
  26. #include "zoo.h"
  27. #include "errors.i"
  28. #include "zooio.h"
  29. #include "various.h"
  30. #include "zoofns.h"
  31.  
  32. #ifdef TRACE_LIST
  33. void show_dir PARMS ((struct direntry *direntry));
  34. static int trace_list = 0;
  35. #endif /* TRACE_LIST */
  36.  
  37. static char tot_fmt[] = "%8lu %3u%% %8lu  %4d file";
  38. static char tot_line[] =
  39.    /* "------------  --------  ---  --------  --------- --------\n"; */
  40.    "--------  --- --------  --------- --------\n";
  41.  
  42. static char dbl_percent[] = "Archive %s:  %s";
  43.  
  44. extern int quiet;                /* assumed initialized to zero */
  45.  
  46. void show_comment PARMS((struct direntry *, ZOOFILE, int, char *));
  47. int ver_too_high PARMS((struct zoo_header *));
  48. int needed PARMS((char *, struct direntry *, struct zoo_header *));
  49. void printtz PARMS((int));
  50.  
  51. void zoolist (argv, option, argc)
  52. char **argv, *option;
  53. int argc;
  54. {
  55. char whichname[PATHSIZE];  /* which name to use */
  56. char *this_zoo;            /* currently matched archive name */
  57. register ZOOFILE zoo_file;
  58. char *flist[ZOOCOUNT];       /* list of ptrs to input archive names */
  59. int fptr;                  /* will point to within list of archive names */
  60.  
  61. struct direntry direntry;
  62. struct zoo_header zoo_header;
  63. int size_factor;
  64. unsigned long tot_org_siz = 0L, tot_siz_now = 0L;
  65. int   tot_sf;
  66. int file_count = 0;
  67. int del_count = 0;                  /* number of deleted entries */
  68. int bad_pack;                 /* 1 if packing method is unknown */
  69. static char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
  70. static char dashes[] = "------------\n";
  71. int year, month, day, hours, min, sec;
  72. int list_deleted = 0;         /* list deleted files too */
  73. int fast = 0;                 /* fast list */
  74. long fiz_ofs = 0;             /* offset where to start */
  75. long dat_ofs = 0;             /* ... data offset of file data */
  76. int verb_list = 0;            /* if verbose listing needed */
  77. int show_name = 0;            /* if archive name to be included in listing */
  78. int show_crc = 0;                    /* if crc should be listed */
  79. int zoocount = 1;             /* number of archives to list */
  80. int biglist = 0;              /* multiarchive listing */
  81. int one_col = 0;                    /* one column listing requested */
  82. int showdir = 0;                    /* show directory name in fast listing */
  83. int longest;                  /* length of longest archive name */
  84. int talking;                        /* opposite of quiet */
  85. int column = 0;               /* for column printing */
  86. int first_ever = 1;                /* first time ever -- very special case */
  87. int neednl = 0;                    /* whether to print a newline */
  88. int need_acmt = 0;                /* show archive comment */
  89. int show_gen = 0;                    /* show generation count */
  90. int genson = 1;                    /* enable/disable generations */
  91. #ifdef FATTR
  92. int show_mode = 0;                /* show file protection */
  93. #endif
  94. int first_dir = 1;                /* if first direntry -- to adjust dat_ofs */
  95.  
  96. while (*option) {
  97.    switch (*option) {
  98.       case 'a': show_name++; break;
  99. #ifdef TRACE_LIST
  100.         case 'D': trace_list++; break;
  101. #endif /* TRACE_LIST */
  102.       case 'd': list_deleted++; break;
  103.       case 'f': fast++; break;
  104.         case 'g': show_gen++; break;
  105.         case '/': showdir++; break;
  106.         case 'A':
  107.         case 'v': need_acmt++; break;
  108.       case 'V': need_acmt++; /* fall through */
  109.       case 'c': verb_list++; break;
  110.         case 'C': show_crc++; break;
  111.       case 'l': break;
  112.       case 'L': biglist++; zoocount = argc; break;
  113. #ifdef FATTR
  114.         case 'm': show_mode++; break;
  115. #endif
  116.         case '1': one_col++; break;
  117.         case '+': genson = 1; break;
  118.         case '-': genson = 0; break;
  119.         /* following code same as in zooext.c */
  120.       case '@':     /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
  121.             {
  122.                 char *comma_pos;
  123.                 ++option;
  124.                 comma_pos = strchr(option, ',');
  125.                 if (comma_pos != NULL) {
  126.                     dat_ofs = calc_ofs (comma_pos + 1);
  127.                     *comma_pos = '\0';
  128.                 }
  129.                 fiz_ofs = calc_ofs(option); 
  130.                 goto no_more;
  131.             }
  132.         case 'q': quiet++; break;
  133.       default:
  134.          prterror ('w', option_ignored, *option);
  135.    }
  136.    option++;
  137. }
  138.  
  139. no_more:  /* come from exit from while loop above */
  140.  
  141. if (fast && show_name) {      /* don't allow 'a' with 'f' */
  142.    show_name = 0;
  143.    prterror ('w', option_ignored, 'a');
  144. }
  145.  
  146. talking = !quiet;                    /* for convenience */
  147.  
  148. #ifdef WILDCARD
  149.    /* For each archive name supplied, if it is not a char range and
  150.       does not contain a dot, append "*.zoo". */
  151.    {
  152.       int i;
  153.       for (i = 0; i < argc;  i++) {
  154.          if (strchr (nameptr (argv[i]), EXT_CH) == NULL && 
  155.                            !match_half (nameptr (argv[0]), "?-?"))
  156.             argv[i] = newcat (argv[i], "*.zoo");
  157.       }
  158.    }
  159. #endif
  160.  
  161. makelist (zoocount, argv, flist,        ZOOCOUNT-2,   (char *) NULL,".","..", &longest);
  162. /*        ^argc     ^argv ^list_pointer ^max_no_files   ^exclude */
  163.  
  164. for (fptr = 0;  (this_zoo = flist[fptr]) != NULL; fptr++) {
  165.    int ercount;                  /* count of errors */
  166.    int entrycount;               /* count of directory entries */
  167.    int expl_deleted;             /* explain what D means */
  168.    int expl_comment;             /* explain what comment means */
  169.    int expl_ver;                 /* Explain what V means */
  170.    int expl_star;                /* Explain what * means */
  171.    int first_time;               /* first time through loop for an archive */
  172.  
  173.    ercount = entrycount = del_count =
  174.       expl_deleted = expl_comment = expl_ver = expl_star = 0;
  175.  
  176.     if (talking)
  177.         column = 0;                        /* if quiet, names will run together */
  178.  
  179.    first_time = 1;
  180.  
  181. #ifndef WILDCARD
  182.    /* Add default extension if none supplied */
  183.    if (strchr (nameptr (this_zoo), EXT_CH) == NULL)
  184.       this_zoo = newcat (this_zoo, EXT_DFLT);
  185. #endif
  186.  
  187.    zoo_file = zooopen (this_zoo, Z_READ);
  188.  
  189.    if (zoo_file == NOFILE) {
  190.       prterror ('e', could_not_open, this_zoo);
  191.       continue;
  192.    } else if (!show_name && talking)
  193.       printf ("\nArchive %s:\n", this_zoo);
  194.    
  195. if (fiz_ofs != 0L) {                /* if offset specified, start there */
  196.     prterror ('m', start_ofs, fiz_ofs, dat_ofs);
  197.    zooseek (zoo_file, fiz_ofs, 0);
  198. } else {
  199.    if (frd_zooh (&zoo_header, zoo_file) == -1 ||
  200.                                              zoo_header.zoo_tag != ZOO_TAG) {
  201.       prterror ('e', dbl_percent, this_zoo, invalid_header);
  202.       goto loop_end;
  203.    }
  204. #if 0
  205.     if (talking && (!show_name || verb_list || need_acmt))
  206. #else
  207.     if (need_acmt && talking)
  208. #endif
  209.     {
  210.         void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
  211.         show_acmt (&zoo_header, zoo_file, 0);        /* show archive comment */
  212.     }
  213.  
  214.    /* Seek to the beginning of the first directory entry */
  215.    if (zooseek (zoo_file, zoo_header.zoo_start, 0) != 0) {
  216.       ercount++;
  217.       prterror ('e', dbl_percent, this_zoo, bad_directory);
  218.       goto loop_end;
  219.    }
  220.    if (!show_name && ver_too_high (&zoo_header)) {
  221.       ercount++;
  222.       if (ercount < 2)
  223.          prterror ('M', wrong_version, 
  224.                                         zoo_header.major_ver, zoo_header.minor_ver);
  225.    }
  226. } /* end if (fiz_ofs !- 0L) */
  227.  
  228.    /* Now we print information about each file in the archive */
  229.    
  230.    if (!show_name) { /* initialize for each file only if not disk catalog */
  231.       tot_org_siz = 0L;  
  232.       tot_siz_now = 0L;
  233.       file_count = 0;
  234.       del_count = 0;
  235.    }
  236.  
  237.    while (1) {
  238. #ifndef GLOB
  239.       if (readdir (&direntry, zoo_file, 0) == -1) {
  240. #else
  241.       if (zreaddir (&direntry, zoo_file, 0) == -1) {
  242. #endif /* GLOB */
  243.          prterror ('F', dbl_percent, this_zoo, bad_directory);
  244.          goto givesummary;
  245.       }
  246.       if (direntry.zoo_tag != ZOO_TAG) {
  247.          long currpos, zoolength;
  248.          prterror ('F', dbl_percent, this_zoo, invalid_header);
  249.          if ((currpos = zootell (zoo_file)) != -1L)
  250.             if (zooseek (zoo_file, 0L, 2) == 0)
  251.                if ((zoolength = zootell (zoo_file)) != -1L)
  252.                   printf (cant_process, zoolength - currpos);              
  253.          goto givesummary;
  254.       }
  255.    
  256.       if (direntry.next == 0L)      /* EXIT on end of chain */
  257.          break;                                 
  258.       else
  259.          entrycount++;              /* Number of directory entries */
  260.         /* first direntry read, change dat_ofs from abs. pos. to rel. offset */
  261.         if (first_dir && dat_ofs != 0) {
  262.             dat_ofs -= direntry.offset;
  263.             first_dir = 0;
  264.         }
  265.         direntry.next += dat_ofs;                /* allow for user-specified offset */
  266.         if (direntry.comment != 0L)
  267.             direntry.comment += dat_ofs;        /* so show_comment finds it */
  268.    
  269.       if (direntry.deleted)
  270.          ++del_count;
  271.  
  272. #ifdef TRACE_LIST
  273.         if (trace_list)
  274.             show_dir (&direntry);
  275. #endif /* TRACE_LIST */
  276.       
  277.         /* Into `whichname' put the filename to display. Use long filename if 
  278.         it exists, else use short filename.  */
  279.             strcpy (whichname, fullpath (&direntry));
  280.             if (zoo_header.vdata & VFL_ON)
  281.                 add_version (whichname, &direntry);    /* add version suffix */
  282. #ifdef DEBUG
  283.       printf("matching against [%s] and [%s]\n", 
  284.                nameptr(whichname), whichname);
  285. #endif
  286.  
  287.       if ( ( (list_deleted && direntry.deleted) ||
  288.                (list_deleted < 2 && !direntry.deleted)
  289.            ) 
  290.               && (biglist || needed(whichname, &direntry, &zoo_header))) {
  291.             /* if generations forced off, then strip added version field */
  292.             if (!genson) {    /* HORRENDOUSLY INEFFICIENT AND REPETITIOUS */
  293.                 char *ver_pos;
  294.                 ver_pos = findlast (whichname, VER_DISPLAY);
  295.                 if (ver_pos != NULL)
  296.                     *ver_pos = '\0';
  297.             }
  298.    
  299.          file_count++;
  300.    
  301.          if (direntry.packing_method > MAX_PACK) {
  302.             bad_pack = 1;
  303.             expl_ver = 1;
  304.          }  else
  305.             bad_pack = 0;
  306.       
  307.          size_factor = cfactor (direntry.org_size, direntry.size_now);
  308.    
  309.          year  =  ((unsigned int) direntry.date >> 9) & 0x7f;
  310.          month =  ((unsigned int) direntry.date >> 5) & 0x0f;
  311.          day   =  direntry.date        & 0x1f;
  312.    
  313.          hours =  ((unsigned int) direntry.time >> 11)& 0x1f;
  314.          min   =  ((unsigned int) direntry.time >> 5) & 0x3f;
  315.          sec   =  ((unsigned int) direntry.time & 0x1f) * 2;
  316.    
  317.             /* Alignment in columns is a horrendously complex undertaking. */
  318.  
  319.          if (fast) {
  320.                 int space_left;
  321.                 int namelen;
  322.                 int next_col;
  323. #if 0
  324.             if ( (quiet && !first_ever || !first_time) && one_col)
  325.                fputchar ('\n');
  326.                 first_ever = 0;
  327. #endif
  328.                 /* If we are showing directories, whichname already contains the
  329.                 full pathname string.  Else we only use the filename as follows:
  330.                 long filename if possible, else short filename */
  331.                 if (!showdir) {
  332.                    strcpy (whichname, 
  333.                       (direntry.namlen != 0) ? direntry.lfname : direntry.fname);
  334.                     if (genson && zoo_header.vdata & VFL_ON)
  335.                         add_version (whichname, &direntry);    /* add version suffix */
  336.                 }
  337.                 namelen = strlen (whichname);
  338.  
  339. #define MARGIN            78
  340. #define COL_WIDTH        16
  341. #if 1
  342.                 /* if not enough space left, move to next line */
  343.                 if (!one_col && column != 0) {
  344.                     space_left = MARGIN - column;
  345.                     if (namelen > space_left) {
  346.                         neednl = 1;
  347.                         column = 0;
  348.                     }
  349.                 }
  350. #endif
  351.             if ( (quiet && !first_ever || !first_time) && (neednl || one_col))
  352.                     printf ("\n");
  353.                 first_ever = 0;
  354.                 neednl = 0;
  355.  
  356.             printf("%s", whichname);
  357.                 fflush (stdout);
  358.                 /* move to next column stop */
  359.                 column += namelen;
  360.                 next_col = ((column + (COL_WIDTH - 1)) / COL_WIDTH) * COL_WIDTH;
  361.                 if (next_col - column < 2)        /* need at least 2 spaces */
  362.                     next_col += COL_WIDTH;
  363.                 if (next_col > MARGIN) {
  364.                     neednl = 1;
  365.                     column = 0;
  366.                 } else {
  367.                     if (!one_col)
  368.                         printf ("%*s", (next_col - column), " ");
  369.                     column = next_col;
  370.                 }
  371.    
  372.          } else {
  373.             if (talking && first_time && !show_name) {/*print archive header */
  374.                printf ("Length    CF  Size Now  Date      Time\n");
  375.                printf (tot_line);
  376.             }
  377.             printf ("%8lu %3u%% %8lu  %2d %-.3s %02d %02d:%02d:%02d",  
  378.                      direntry.org_size, 
  379.                      size_factor, direntry.size_now, 
  380.                      day, &month_list[month*3], 
  381.                      (day && month) ?  (year+80) % 100 : 0,
  382.                      hours, min, sec);
  383.                tot_org_siz += direntry.org_size;
  384.                tot_siz_now += direntry.size_now;
  385. #ifdef GETTZ
  386.                 printtz ((int) direntry.tz);    /* show timezone */
  387. #else
  388.                 printf (" ");
  389. #endif
  390.  
  391.                 if (show_crc)
  392.                     printf ("%04x ", direntry.file_crc);
  393.                 if (show_gen) {
  394.                     if (direntry.vflag & VFL_ON)
  395.                         printf ("%2dg ", direntry.vflag & VFL_GEN);
  396.                     else
  397.                         printf ("--g ");
  398.                 }
  399.    
  400.             if (direntry.cmt_size) {
  401.                expl_comment++;
  402.                printf ("C");
  403.             } else
  404.                printf (" ");
  405.    
  406.             if (direntry.deleted) {
  407.                expl_deleted++;
  408.                printf ("D");
  409.             }  else
  410.                printf (" ");
  411.             if (list_deleted)
  412.                printf (" ");
  413.             if (show_name)
  414.                printf ("%-*s ", longest, this_zoo);
  415.  
  416. #ifdef FATTR
  417.                 if (show_mode) {
  418.                     if (direntry.fattr == 0)
  419.                         printf ("--- ");
  420.                     else if ((direntry.fattr >> 22) == 1)
  421.                         printf ("%03o ", direntry.fattr & 0x1ff);
  422.                     else
  423.                         printf ("??? ");
  424.                 }
  425. #endif /* FATTR */
  426.  
  427.                 /* new code to get around a common compiler bug */
  428.                 printf ("%s", whichname);
  429.                 if (direntry.dir_crc != 0) {
  430.                     expl_star++;
  431.                     printf ("*");
  432.                 }
  433.  
  434.             if (bad_pack)
  435.                printf (" (V%d.%d)", direntry.major_ver, direntry.minor_ver);
  436.             printf ("\n");
  437.          }
  438.          first_time = 0;
  439.    
  440.          /* if verbose listing requested show any comment.  f overrrides v */
  441.          if (verb_list && !fast)
  442.             show_comment (&direntry, zoo_file, 0, (char *) NULL);
  443.       } /* end if (lots of conditions) */
  444.    
  445.         /* ..seek to next dir entry */
  446.       zooseek (zoo_file, direntry.next, 0);
  447.    } /* end while */
  448.    
  449.    givesummary:
  450.    
  451.     if (fast && talking) {
  452.        if (file_count) {
  453.            if (del_count || (show_gen && zoo_header.type > 0))
  454.               printf ("\n-----\n");
  455.             else
  456.               fputchar ('\n');
  457.         }
  458.         if (del_count)
  459.             printf ("%d deleted.\n", del_count);
  460.         if (show_gen && zoo_header.type > 0) {
  461.             printf ("Generation limit %u",
  462.                         zoo_header.vdata & VFL_GEN);
  463.             if ((zoo_header.vdata & VFL_ON) == 0)
  464.                 printf (" (off).\n");
  465.             else
  466.                 printf (".\n");
  467.         }
  468.     } /* end if (fast && talking) */
  469.  
  470.    if (talking && !show_name) {
  471.       if (!fast && file_count) {
  472.          tot_sf = cfactor (tot_org_siz, tot_siz_now);
  473.          printf (tot_line);
  474.       
  475.          printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
  476.             if (file_count > 1)
  477.                 printf ("s\n");
  478.             else
  479.                 printf ("\n");
  480.          
  481.          if (del_count || expl_ver || expl_deleted || expl_comment ||
  482.                     expl_star || (show_gen && (zoo_header.type > 0)))
  483.             printf (dashes);
  484.       }
  485.    
  486.       if (!fast) {
  487.          if (del_count) {
  488.             if (expl_deleted)
  489.                printf ("D: deleted file.\n");
  490.             else {
  491.                if (del_count == 1)
  492.                   printf ("There is 1 deleted file.\n");
  493.                else
  494.                   printf ("There are %d deleted files.\n", del_count);
  495.             }
  496.          }
  497.       }
  498.       if (expl_comment && !fast && !verb_list) 
  499.          printf ("C: file has attached comment.\n");
  500.       if (expl_ver && !fast)
  501.          printf ("V: minimum version of Zoo needed to extract this file.\n");
  502.       if (expl_star && !fast)
  503.          printf ("*: directory entry may be corrupted.\n");
  504.       if (!file_count)
  505.          printf ("Zoo:  %s", no_match);
  506.       
  507.       if (!entrycount && !fiz_ofs)
  508.          printf ("(The archive is empty.)\n");
  509.         if (show_gen && (zoo_header.type > 0) && !fast) {
  510.             printf ("Archive generation limit is %u",
  511.                         zoo_header.vdata & VFL_GEN);
  512.             if ((zoo_header.vdata & VFL_ON) == 0)
  513.                 printf (" (generations off).\n");
  514.             else
  515.                 printf (".\n");
  516.         }
  517.    } /* end if (talking && !show_name) */
  518. loop_end:            /* jump here on badly structured archive */
  519.    zooclose (zoo_file);
  520. } /* end for */
  521.  
  522. if (talking && show_name) {
  523.    if (file_count) {
  524.       tot_sf = cfactor (tot_org_siz, tot_siz_now);
  525.       printf (tot_line);
  526.       printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
  527.         if (file_count > 1)
  528.             printf ("s\n");
  529.         else
  530.             printf ("\n");
  531.    } 
  532. } else if (fast && quiet)
  533.     fputchar ('\n');
  534.     
  535.  
  536. if (!file_count)
  537.    zooexit (1);            /* Consider it an error if there were no files */
  538. } /* zoolist() */
  539.  
  540. #ifdef GETTZ
  541. void printtz (file_tz)
  542. int file_tz;
  543. {
  544.     long gettz PARMS((void));
  545.     int diff_tz;                /* timezone difference */
  546.     if (file_tz == NO_TZ)     /* if no timezone stored ..*/
  547.         printf ("   ");            /* .. just pad with blanks */
  548.     else {
  549.         diff_tz = (file_tz / 4) - (int) (gettz() / 3600);
  550.         if (diff_tz == 0)
  551.             printf ("   ");                    /* print nothing if same */
  552.         else if (diff_tz > 0)            /* else print signed difference */
  553.             printf ("+%1d ", diff_tz);
  554.         else
  555.             printf ("-%1d ", -diff_tz);
  556.     }
  557. }
  558. #endif
  559.  
  560. /*
  561. FOLLOWING CODE IS FOR DEBUGGING ONLY.  IT IS COMPILED IN ONLY
  562. IF THE SYMBOL TRACE_LIST IS DEFINED
  563. */
  564.  
  565. #ifdef TRACE_LIST
  566. /* code copied from portable.c near end */
  567. /* dump contents of directory entry */
  568. void show_dir (direntry)
  569. struct direntry *direntry;
  570. {
  571.    printf ("Directory entry for file [%s][%s]:\n",
  572.             direntry->fname, direntry->lfname);
  573.    printf ("tag = [%8lx] type = [%d] PM = [%d] Next = [%8lx] Offset = [%8lx]\n",
  574.             direntry->zoo_tag, (int) direntry->type, 
  575.             (int) direntry->packing_method, direntry->next, 
  576.             direntry->offset);
  577.    printf ("Orig size = [%ld] Size now = [%ld] dmaj_v.dmin_v = [%d.%d]\n",
  578.          direntry->org_size, direntry->size_now,
  579.          (int) direntry->major_ver, (int) direntry->minor_ver);
  580.    printf ("Struc = [%d] DEL = [%d] comment_offset = [%8lx] cmt_size = [%d]\n",
  581.          (int) direntry->struc, (int) direntry->deleted, direntry->comment,
  582.          direntry->cmt_size);
  583.    printf ("var_dir_len = [%d] TZ = [%d] dir_crc = [%4x]\n",
  584.             direntry->var_dir_len, (int) direntry->tz, direntry->dir_crc);
  585.    printf ("system_id = [%d]  dirlen = [%d]  namlen = [%d] fattr=[%24lx]\n", 
  586.         direntry->system_id, direntry->dirlen, direntry->namlen, direntry->fattr);
  587.     printf ("vflag = [%4x] version_no = [%4x]\n",
  588.                 direntry->vflag, direntry->version_no);
  589.    if (direntry->dirlen > 0)
  590.       printf ("dirname = [%s]\n", direntry->dirname);
  591.    printf ("---------\n");
  592. }
  593. #endif   /* TRACE_IO */
  594.